from django.conf import settings
from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponseForbidden, HttpResponse, HttpRequest
from django.shortcuts import render_to_response
from django.template import Context, loader, RequestContext
from django import forms
from django.contrib.auth.views import login
from django.contrib.auth import logout
from django.contrib.auth.models import User
from rpgEngine.models import Message, Master, Player, rpgEngineHelper, MESSAGE_PER_PAGE, ITEM_PER_PAGE, LibraryItem, InventoryItem, CharacterSheet, Game, Notes
from django.db import connection
from datetime import datetime
import os
from django.core.exceptions import ObjectDoesNotExist
from django.utils.html import escape


def logoutUser(request):
	logout(request)
	return HttpResponseRedirect("/")

class characterForm(forms.Form):
	busy_with = forms.CharField(required=False, widget=forms.Textarea(attrs={'id':'char_busy_with', 'onkeyup':'changedOccured()'}))
	location_time = forms.CharField(required=False, widget=forms.Textarea(attrs={'id':'char_location_time', 'onkeyup':'changedOccured()'}))
	general_carac = forms.CharField(required=False, widget=forms.Textarea(attrs={'id':'char_general_carac', 'onkeyup':'changedOccured()'}))
	carac_reaction = forms.CharField(required=False, widget=forms.Textarea(attrs={'id':'char_carac_reaction', 'onkeyup':'changedOccured()'}))
	advantage_disadvantage = forms.CharField(required=False, widget=forms.Textarea(attrs={'id':'char_advantage_disadvantage', 'onkeyup':'changedOccured()'}))
	skills = forms.CharField(required=False, widget=forms.Textarea(attrs={'id':'char_skills', 'onkeyup':'changedOccured()'}))
	defense = forms.CharField(required=False, widget=forms.Textarea(attrs={'id':'char_defense', 'onkeyup':'changedOccured()'}))
	movement = forms.CharField(required=False, widget=forms.Textarea(attrs={'id':'char_movement', 'onkeyup':'changedOccured()'}))
	dark_corner = forms.CharField(required=False, widget=forms.Textarea(attrs={'id':'char_dark_corner', 'onkeyup':'changedOccured()'}))
	
def character(request):
	if rpgEngineHelper.getPlayer(request.user) == None:
		return HttpResponseForbidden()
	menu = rpgEngineHelper.getMenuList(request.user)
	rpgEngineHelper.updatePresence(request.user)
	try:
		ch = CharacterSheet.objects.get(player_id__exact=request.user.id)
	except ObjectDoesNotExist :
		#create the character sheet of the user in db
		ch = CharacterSheet()
		ch.player_id = request.user.id
		ch.save()
	if (request.method == 'POST'):
		#character sheet has been modified, extract data and save it
		f = characterForm(request.POST, auto_id=True)
		if f.is_valid():
			ch.busy_with = f.cleaned_data['busy_with']
			ch.location_time = f.cleaned_data['location_time']
			ch.general_carac = f.cleaned_data['general_carac']
			ch.carac_reaction = f.cleaned_data['carac_reaction']
			ch.advantage_disadvantage = f.cleaned_data['advantage_disadvantage']
			ch.skills = f.cleaned_data['skills']
			ch.defense = f.cleaned_data['defense']
			ch.movement = f.cleaned_data['movement']
			ch.dark_corner = f.cleaned_data['dark_corner']
			ch.save()
			#positive ack
			return HttpResponse("ok")
		else:
			#negative ack
			return HttpResponse("nok")
	data = {'busy_with':ch.busy_with,
		'location_time':ch.location_time,
		'general_carac':ch.general_carac,
		'carac_reaction':ch.carac_reaction,
		'advantage_disadvantage':ch.advantage_disadvantage,
		'skills':ch.skills,
		'defense':ch.defense,
		'movement':ch.movement,
		'dark_corner':ch.dark_corner}
	form = characterForm(data, auto_id=True)
	#get last post date
	cursor = connection.cursor()
	query =  "SELECT MAX(date) FROM rpgEngine_message WHERE origId = "+str(request.user.id)
	cursor.execute(query)
	last_post = cursor.fetchone()[0]
	game_id = rpgEngineHelper.getGameId(request.user)
	stickyBox = rpgEngineHelper.getStickyBox(game_id)
	return render_to_response('rpgEngine/characterBase.html', {
		'menu':menu,
		'stickyBox':stickyBox,
		'form':form,
		'first_n':request.user.first_name,
		'last_n':request.user.last_name,
		'char_sheet':ch,
		'last_login':request.user.last_login,
		'last_post':last_post
	}, context_instance=RequestContext(request))


def characterPrint(request):
	if rpgEngineHelper.getPlayer(request.user) == None:
		return HttpResponseForbidden()
	menu = rpgEngineHelper.getMenuList(request.user)
	rpgEngineHelper.updatePresence(request.user)
	try:
		ch = CharacterSheet.objects.get(player_id__exact=request.user.id)
	except ObjectDoesNotExist :
		#create the character sheet of the user in db
		ch = CharacterSheet()
		ch.player_id = request.user.id
		ch.save()
	#get last post date
	cursor = connection.cursor()
	query =  "SELECT MAX(date) FROM rpgEngine_message WHERE origId = "+str(request.user.id)
	cursor.execute(query)
	last_post = cursor.fetchone()[0]
	return render_to_response('rpgEngine/characterPrint.html', {
		'first_n':request.user.first_name,
		'last_n':request.user.last_name,
		'last_login':request.user.last_login,
		'last_post':last_post,
		'busy_with':escape(ch.busy_with).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'location_time':escape(ch.location_time).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'general_carac':escape(ch.general_carac).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'carac_reaction':escape(ch.carac_reaction).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'advantage_disadvantage':escape(ch.advantage_disadvantage).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'skills':escape(ch.skills).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'defense':escape(ch.defense).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'movement':escape(ch.movement).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'dark_corner':escape(ch.dark_corner).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
	}, context_instance=RequestContext(request))


class notesForm(forms.Form):
	content = forms.CharField(required=False, widget=forms.Textarea(attrs={'class':'notes_form_content', 'onkeyup':'changedOccured()'}))

def notes(request):
	if (rpgEngineHelper.getPlayer(request.user) == None) and (rpgEngineHelper.getMaster(request.user) == None):
		return HttpResponseForbidden()
	menu = rpgEngineHelper.getMenuList(request.user)
	rpgEngineHelper.updatePresence(request.user)
	try:
		n = Notes.objects.get(player_id__exact=request.user.id)
	except ObjectDoesNotExist :
		#create the Notes of the user in db
		n = Notes()
		n.player_id = request.user.id
		n.save()
	if (request.method == 'POST'):
		#character sheet has been modified, extract data and save it
		f = notesForm(request.POST, auto_id=True)
		if f.is_valid():
			n.body = f.cleaned_data['content']
			n.save()
			#positive ack
			return HttpResponse("ok")
		else:
			#negative ack
			return HttpResponse("nok")
	data = {'content':n.body, }
	form = notesForm(data, auto_id=True)
	original = n.body
	game_id = rpgEngineHelper.getGameId(request.user)
	stickyBox = rpgEngineHelper.getStickyBox(game_id)
	return render_to_response('rpgEngine/notes.html', {
		'menu':menu,
		'stickyBox':stickyBox,
		'form':form,
		'original':original,
	}, context_instance=RequestContext(request))


class messageForm(forms.Form):
	destination = forms.CharField(widget=forms.Textarea(attrs={'class':'message_dest', 'onclick':'addrSuggest();', 'readonly':'readonly'}))
	body = forms.CharField(widget=forms.Textarea(attrs={'class':'message_body', 'onfocus':'hideSuggest();'}))


def messageBox(request, beginAt="0"):
	if (rpgEngineHelper.getPlayer(request.user) == None) and (rpgEngineHelper.getMaster(request.user) == None):
		return HttpResponseForbidden()
	#load the menu
	menu = rpgEngineHelper.getMenuList(request.user)
	rpgEngineHelper.updatePresence(request.user)
	isError = False
	form = messageForm(auto_id=True)
	cursor = connection.cursor()
	gameId = rpgEngineHelper.getGameId(request.user)
	#show last post just after posted it
	showLastPost = False
	if (request.method == 'POST'):
		#a message has been submited, extract data and post it
		f = messageForm(request.POST, auto_id=True)
		if f.is_valid():
			destination = f.cleaned_data['destination']
			l = destination.split("; ")
			destIdList = []
			#get player and master in a list
			query =  "SELECT auth_user.id, auth_user.first_name, auth_user.last_name FROM auth_user, rpgEngine_player WHERE auth_user.id = rpgEngine_player.id AND rpgEngine_player.gameId = "+str(gameId)
			cursor.execute(query)
			userList = list(cursor.fetchall())
			query =  "SELECT auth_user.id, auth_user.first_name, auth_user.last_name FROM auth_user, rpgEngine_master WHERE auth_user.id = rpgEngine_master.id AND rpgEngine_master.gameId = "+str(gameId)
			cursor.execute(query)
			userList.append(cursor.fetchone())
			#replace the list of first_name & last_name with list of id
			for i in range(0, len(l)):
				for j in range(0, len(userList)):
					if ((userList[j][1]+" "+userList[j][2]) == l[i]):
						destIdList.append(str(userList[j][0]))
			m = Message()
			m.origId = request.user.id
			m.destId = ";".join(destIdList)
			m.unread = ";".join(destIdList)
			m.body = f.cleaned_data['body']
			#escape javascript injections
			m.body = m.body.replace(">", "&gt;").replace("<", "&lt;")
			m.body = rpgEngineHelper.executeTags(m.body)
			m.body = rpgEngineHelper.execute_style_tag(m.body, gameId)
			m.date = datetime.now()
			m.save()
			showLastPost = True
		else :
			isError = True;
			form = f
	#get the total number of messages
	query = "SELECT count(*) FROM rpgEngine_message"+\
				" WHERE origId = "+str(request.user.id)+" OR destId = "+str(request.user.id)+\
				" OR destId LIKE '"+str(request.user.id)+";%%'"+\
				" OR destId LIKE '%%;"+str(request.user.id)+"'"+\
				" OR destId LIKE '%%;"+str(request.user.id)+";%%'"+\
				" ORDER BY date DESC"
	cursor.execute(query)
	numOfMessages = cursor.fetchone()[0]
	numOfPages = numOfMessages / MESSAGE_PER_PAGE
	if ((numOfPages * MESSAGE_PER_PAGE) < numOfMessages):
		numOfPages += 1
	selectedPage = int(beginAt) / MESSAGE_PER_PAGE
	#load the message list
	messages = rpgEngineHelper.getMessages(request.user, beginAt)
	stickyBox = rpgEngineHelper.getStickyBox(gameId)
	if showLastPost:
		for i in range(0, len(messages)):
			if not messages[i][5] == "header_collapsed_new" :
				messages[i][5] = "header"
				messages[i][6] = "content"
				break;
	return render_to_response('rpgEngine/messageBox.html', {
		'menu':menu,
		'stickyBox':stickyBox,
		'messages':messages,
		'selectedPage':selectedPage + 1,
		'numOfPages':str(numOfPages),
		'form':form,
		'isError':isError,
		'msgPerPage':MESSAGE_PER_PAGE,
	}, context_instance=RequestContext(request))


class inventoryForm(forms.Form):
	name = forms.CharField(widget=forms.TextInput(attrs={'class':'inventory_form_name', 'autocomplete':'off',}))
	description = forms.CharField(initial='description...', widget=forms.Textarea(attrs={'class':'inventory_form_description','onfocus':'description_onfocus(this);','onblur':'description_onblur(this);'}))
	quantity = forms.CharField(widget=forms.TextInput(attrs={'class':'inventory_form_quantity', 'autocomplete':'off',}))
	isEdit = forms.IntegerField(widget=forms.HiddenInput(), required=False)


def inventory(request, beginAt="0", editId="-1"):
	if (rpgEngineHelper.getPlayer(request.user) == None):
		return HttpResponseForbidden()
	isError = False
	form = inventoryForm(auto_id=True)
	cursor = connection.cursor()
	if (request.method == 'POST'):
		#an inventory item has been submited, extract data and post it
		f = inventoryForm(request.POST, auto_id=True)
		if f.is_valid():
			#in cas quantity is not a number, and ??
			try:
				if (f.cleaned_data['isEdit'] != None):
					#an id is passed in hidden field, item is to be updated
					i = InventoryItem.objects.get(id__exact=f.cleaned_data['isEdit'])
					if not(request.user.id == i.userId):
						return HttpResponseForbidden()
					#to avoid errors in javascript confirm delete name
					i.name = escape(f.cleaned_data['name'])
					i.description = f.cleaned_data['description']
					i.quantity = f.cleaned_data['quantity']
					i.save()
					#redirect to inventory at freshly modified item
					return HttpResponseRedirect("/inventory/#"+str(f.cleaned_data['isEdit']))
				else:
					#item is to be inserted
					i = InventoryItem()
					i.userId = request.user.id
					#to avoid errors in javascript confirm delete name
					i.name = escape(f.cleaned_data['name'])
					i.description = f.cleaned_data['description']
					i.quantity = f.cleaned_data['quantity']
					i.save()
			except:
				isError = True;
				form = f
		else :
			isError = True;
			form = f
	if (editId != "-1"):
		#an item is to be edited, form is filled up with its data, including id in hidden field
		item = InventoryItem.objects.get(id__exact=editId)
		if not(request.user.id == item.userId):
			return HttpResponseForbidden()
		data = {'name':item.name, 'description':item.description, 'quantity':item.quantity, 'isEdit':editId}
		form = inventoryForm(data, auto_id=True)
	#get the total number of items
	query = "SELECT count(*) FROM rpgEngine_inventoryitem"+\
				" WHERE userId = "+str(request.user.id)
	cursor.execute(query)
	numOfItems = cursor.fetchone()
	numOfPages = numOfItems[0] / ITEM_PER_PAGE
	if ((numOfPages * ITEM_PER_PAGE) < numOfItems[0]):
		numOfPages += 1
	pageSelector = ["<select onchange=\"window.location.href = this.value\">",]
	selectedPage = int(beginAt) / ITEM_PER_PAGE
	for j in range(0, numOfPages):
		if j == selectedPage:
			pageSelector.append("<option selected='selected' value='/inventory/"+str(j*ITEM_PER_PAGE)+"/'>Page "+str(j+1)+"&nbsp;</option>")
		else:
			pageSelector.append("<option value='/inventory/"+str(j*ITEM_PER_PAGE)+"/'>Page "+str(j+1)+"&nbsp;</option>")
	pageSelector.append("</select>")
	#load the item list
	items = rpgEngineHelper.getInventoryItems(request.user, beginAt)
	#load the menu
	menu = rpgEngineHelper.getMenuList(request.user)
	rpgEngineHelper.updatePresence(request.user)
	gameId = rpgEngineHelper.getGameId(request.user)
	stickyBox = rpgEngineHelper.getStickyBox(gameId)
	return render_to_response('rpgEngine/inventory.html', {
		'menu':menu,
		'items':items,
		'form':form,
		'isError':isError,
		'pageSelect':"".join(pageSelector),
		'beginAt':beginAt,
		'stickyBox':stickyBox,
	}, context_instance=RequestContext(request))


def inventoryPrint(request):
	if (rpgEngineHelper.getPlayer(request.user) == None):
		return HttpResponseForbidden()
	#load the item list
	items = rpgEngineHelper.getInventoryItems(request.user, "-1")
	rpgEngineHelper.updatePresence(request.user)
	return render_to_response('rpgEngine/inventoryPrint.html', {
		'items':items,
		'first_n':request.user.first_name,
		'last_n':request.user.last_name,
	}, context_instance=RequestContext(request))



def delInventoryItem(request, itemId, beginAtRedirect):
	'''delete from Inventory the item with id : id'''
	if (rpgEngineHelper.getPlayer(request.user) == None):
		return HttpResponseForbidden()
	#userGameId = rpgEngineHelper.getGameId(request.user)
	inventoryItem = InventoryItem.objects.get(id=itemId)
	if not(request.user.id == inventoryItem.userId):
		return HttpResponseForbidden()
	else:
		#remove item from data base
		inventoryItem.delete()
		return HttpResponseRedirect("/inventory/"+str(beginAtRedirect)+"/")
		
		

class IscapForm(forms.Form):
	iscap = forms.IntegerField(max_value=999, min_value=0, widget=forms.TextInput(attrs={'class':'iscap_form_field', 'autocomplete':'off',}))


def team(request, editId="-1"):
	if (rpgEngineHelper.getPlayer(request.user) == None) and (rpgEngineHelper.getMaster(request.user) == None):
		return HttpResponseForbidden()
	menu = rpgEngineHelper.getMenuList(request.user)
	game_id = rpgEngineHelper.getGameId(request.user)
	iscapForm = None
	isErrorIscap = None
	if rpgEngineHelper.getMaster(request.user) != None:
		#ISCAP
		isErrorIscap = False
		g = Game.objects.get(id__exact=game_id)
		data = {'iscap':g.iscap, }
		iscapForm = IscapForm(data)
	#chest
	isError = False
	form = inventoryForm(auto_id=True)
	if (request.method == 'POST'):
		if u"addItem" in request.POST:
			f = inventoryForm(request.POST, auto_id=True)
			if f.is_valid():
				#an inventory item has been submited, extract data and post it
				#in case quantity is not a number, and ??
				try:
					if (f.cleaned_data['isEdit'] != None):
						#an id is passed in hidden field, item is to be updated
						i = InventoryItem.objects.get(id__exact=f.cleaned_data['isEdit'])
						master = Master.objects.get(gameId__exact=game_id)
						if not(master.id == i.userId):
							return HttpResponseForbidden()
						#to avoid errors/injection in javascript escape delete name
						i.name = escape(f.cleaned_data['name'])
						i.description = f.cleaned_data['description']
						i.quantity = f.cleaned_data['quantity']
						i.save()
						#redirect to inventory at freshly modified item
						return HttpResponseRedirect("/team/#"+str(f.cleaned_data['isEdit']))
					else:
						#item is to be inserted
						i = InventoryItem()
						master = Master.objects.get(gameId__exact=game_id)
						i.userId = master.id
						#to avoid errors in javascript confirm delete name
						i.name = escape(f.cleaned_data['name'])
						i.description = f.cleaned_data['description']
						i.quantity = f.cleaned_data['quantity']
						i.save()
				except:
					isError = True;
					form = f
			else :
				isError = True;
				form = f
		if u"iscapSave" in request.POST:
			if (rpgEngineHelper.getMaster(request.user) == None):
				return HttpResponseForbidden()
			f = IscapForm(request.POST)
			if f.is_valid():
				#update ISCAP
				g = Game.objects.get(id__exact=game_id)
				g.iscap = f.cleaned_data['iscap']
				g.save()
				iscapForm = f
			else :
				isErrorIscap = True;
				iscapForm = f
	if (editId != "-1"):
		#an item is to be edited, form is filled up with its data, including id in hidden field
		item = InventoryItem.objects.get(id__exact=editId)
		data = {'name':item.name, 'description':item.description, 'quantity':item.quantity, 'isEdit':editId}
		form = inventoryForm(data, auto_id=True)

	#load the item list
	items = rpgEngineHelper.getInventoryItems_team(game_id)
	pageSelect = rpgEngineHelper.getSelectPageTeam(request.user, game_id, -1)
	stickyBox = rpgEngineHelper.getStickyBox(game_id)
	return render_to_response('rpgEngine/team_chest.html', {
		'menu':menu,
		'iscapForm':iscapForm,
		'form':form,
		'items':items,
		'pageSelect':pageSelect,
		'isError':isError,
		'isErrorIscap':isErrorIscap,
		'stickyBox':stickyBox,
	}, context_instance=RequestContext(request))


def delchestItem(request, itemId):
	'''delete from Team : chest the item with id : id'''
	if (rpgEngineHelper.getPlayer(request.user) == None) and (rpgEngineHelper.getMaster(request.user) == None):
		return HttpResponseForbidden()
	gameId = rpgEngineHelper.getGameId(request.user)
	master = Master.objects.get(gameId__exact=gameId)
	inventoryItem = InventoryItem.objects.get(id=itemId)
	if not(master.id == inventoryItem.userId):
		return HttpResponseForbidden()
	else:
		#remove item from data base
		inventoryItem.delete()
		return HttpResponseRedirect("/team/")


def teamPlayer(request, playerId):
	if (rpgEngineHelper.getPlayer(request.user) == None):
		return HttpResponseForbidden()
	u = User.objects.get(id__exact=playerId)
	game_id = rpgEngineHelper.getGameId(request.user)
	#ensure that player is from same game as currennt user
	if game_id != rpgEngineHelper.getGameId(u) :
		return HttpResponseForbidden()
	menu = rpgEngineHelper.getMenuList(request.user)
	rpgEngineHelper.updatePresence(request.user)
	cursor = connection.cursor()
	try:
		ch = CharacterSheet.objects.get(player_id__exact=playerId)
	except ObjectDoesNotExist :
		#create the character sheet of the user in db
		ch = CharacterSheet()
		ch.player_id = playerId
		ch.save()
	#get last post date
	query =  "SELECT MAX(date) FROM rpgEngine_message WHERE origId = "+str(playerId)
	cursor.execute(query)
	last_post = cursor.fetchone()[0]
	#create list of player for the drop down list
	query = "SELECT auth_user.id, auth_user.first_name, auth_user.last_name FROM auth_user, rpgEngine_player"+\
				" WHERE rpgEngine_player.gameId = "+str(game_id)+\
				" AND rpgEngine_player.id = auth_user.id"+\
				" ORDER BY first_name, last_name DESC"
	cursor.execute(query)
	player_list = cursor.fetchall()
	pageSelect = rpgEngineHelper.getSelectPageTeam(request.user, game_id, playerId)
	stickyBox = rpgEngineHelper.getStickyBox(game_id)
	return render_to_response('rpgEngine/team_player.html', {
		'menu':menu,
		'stickyBox':stickyBox,
		'pageSelect':pageSelect,
		'first_n':u.first_name,
		'last_n':u.last_name,
		'last_login':u.last_login,
		'last_post':last_post,
		'busy_with':escape(ch.busy_with).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'location_time':escape(ch.location_time).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'general_carac':escape(ch.general_carac).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'carac_reaction':escape(ch.carac_reaction).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
		'skills':escape(ch.skills).replace('\n',"<br/>").replace('  ',"&nbsp;&nbsp;"),
	}, context_instance=RequestContext(request))


def teamPlayerForMaster(request, playerId, editId="-1", formName = "", delId="-1"):
	if (rpgEngineHelper.getMaster(request.user) == None):
		return HttpResponseForbidden()
	u = User.objects.get(id__exact=playerId)
	game_id = rpgEngineHelper.getGameId(request.user)
	#ensure that master is from same game as viewed/edited user
	if game_id != rpgEngineHelper.getGameId(u) :
		return HttpResponseForbidden()
	onLoadAnchor = "";
	if (delId != "-1"):
		#an item is to be deleted
		item = InventoryItem.objects.get(id__exact=delId)
		if not(playerId == str(item.userId)):
			return HttpResponseForbidden()
		#remove item from data base
		item.delete()
		#return HttpResponseRedirect("/team/playerForMaster/"+playerId+"/#inventoryAnch")
		onLoadAnchor = "#inventoryAnch"
	menu = rpgEngineHelper.getMenuList(request.user)
	rpgEngineHelper.updatePresence(request.user)
	cursor = connection.cursor()
	try:
		ch = CharacterSheet.objects.get(player_id__exact=playerId)
	except ObjectDoesNotExist :
		#create the character sheet of the user in db
		ch = CharacterSheet()
		ch.player_id = playerId
		ch.save()
	isErrorCharacter = False
	if (request.method == 'POST'):
		if formName == "character" :
			#character sheet has been modified, extract data and save it
			f = characterForm(request.POST, auto_id=True)
			if f.is_valid():
				ch.busy_with = f.cleaned_data['busy_with']
				ch.location_time = f.cleaned_data['location_time']
				ch.general_carac = f.cleaned_data['general_carac']
				ch.carac_reaction = f.cleaned_data['carac_reaction']
				ch.advantage_disadvantage = f.cleaned_data['advantage_disadvantage']
				ch.skills = f.cleaned_data['skills']
				ch.defense = f.cleaned_data['defense']
				ch.movement = f.cleaned_data['movement']
				ch.dark_corner = f.cleaned_data['dark_corner']
				ch.save()
			else:
				isErrorCharacter = True
	data = {'busy_with':ch.busy_with,
		'location_time':ch.location_time,
		'general_carac':ch.general_carac,
		'carac_reaction':ch.carac_reaction,
		'advantage_disadvantage':ch.advantage_disadvantage,
		'skills':ch.skills,
		'defense':ch.defense,
		'movement':ch.movement,
		'dark_corner':ch.dark_corner}
	form = characterForm(data, auto_id=True)
	#get last post date
	cursor = connection.cursor()
	query =  "SELECT MAX(date) FROM rpgEngine_message WHERE origId = "+str(playerId)
	cursor.execute(query)
	last_post = cursor.fetchone()[0]
	#inventory
	isErrorInventory = False
	formInventory = inventoryForm(auto_id=True)
	if (request.method == 'POST'):
		if formName == "item" :
			#an inventory item has been submited, extract data and post it
			onLoadAnchor = "#inventoryAnch"
			f = inventoryForm(request.POST, auto_id=True)
			if f.is_valid():
				#in cas quantity is not a number, and ??
				try:
					if (f.cleaned_data['isEdit'] != None):
						#an id is passed in hidden field, item is to be updated
						i = InventoryItem.objects.get(id__exact=f.cleaned_data['isEdit'])
						if not(playerId == str(i.userId)):
							return HttpResponseForbidden()
						#to avoid errors in javascript confirm delete name
						i.name = escape(f.cleaned_data['name'])
						i.description = f.cleaned_data['description']
						i.quantity = f.cleaned_data['quantity']
						i.save()
					else:
						#item is to be inserted
						i = InventoryItem()
						i.userId = playerId
						#to avoid errors in javascript confirm delete name
						i.name = escape(f.cleaned_data['name'])
						i.description = f.cleaned_data['description']
						i.quantity = f.cleaned_data['quantity']
						i.save()
				except:
					isErrorInventory = True;
					formInventory = f
			else :
				isErrorInventory = True;
				formInventory = f
	if (editId != "-1"):
		#an item is to be edited, form is filled up with its data, including id in hidden field
		item = InventoryItem.objects.get(id__exact=editId)
		if not(playerId == str(item.userId)):
			return HttpResponseForbidden()
		data = {'name':item.name, 'description':item.description, 'quantity':item.quantity, 'isEdit':editId}
		formInventory = inventoryForm(data, auto_id=True)
		onLoadAnchor = "#inventoryAnch"
	#load the item list
	items = rpgEngineHelper.getInventoryItems(u, "-1")
	pageSelect = rpgEngineHelper.getSelectPageTeam(request.user, game_id, playerId)
	stickyBox = rpgEngineHelper.getStickyBox(game_id)
	return render_to_response('rpgEngine/team_player_for_master.html', {
		'menu':menu,
		'stickyBox':stickyBox,
		'pageSelect':pageSelect,
		'form':form,
		'first_n':u.first_name,
		'last_n':u.last_name,
		'char_sheet':ch,
		'last_login':u.last_login,
		'last_post':last_post,
		'isErrorCharacter':isErrorCharacter,
		#inventory
		'items':items,
		'formInventory':formInventory,
		'isErrorInventory':isErrorInventory,
		'onLoadAnchor':onLoadAnchor,
	}, context_instance=RequestContext(request))


def teamAddPlayer(request):
	if rpgEngineHelper.getMaster(request.user) == None:
		return HttpResponseForbidden()
	menu = rpgEngineHelper.getMenuList(request.user)
	rpgEngineHelper.updatePresence(request.user)
	form = addPlayerForm(auto_id=True)
	isError = False
	isError_alreay_exist = False
	game_id = rpgEngineHelper.getGameId(request.user)
	if (request.method == 'POST'):
		f_post = addPlayerForm(request.POST, auto_id=True)
		if f_post.is_valid():
			#a player has been submitted
			#check if username already exist
			try:
				u_tmp = User.objects.get(username__exact=f_post.cleaned_data['username'])
				isError_alreay_exist = True
				#keep previously added data in form
				form = f_post
			except User.DoesNotExist:
				pass
			#check if first & last name already exist for the same game
			try:
				cursor = connection.cursor()
				query =  "SELECT count(*)"+\
					" FROM rpgEngine_player, auth_user"+\
					" WHERE rpgEngine_player.id = auth_user.id"+\
					" AND rpgEngine_player.gameId = "+str(game_id)+\
					" AND auth_user.first_name = '"+f_post.cleaned_data['firstname']+"'"+\
					" AND auth_user.last_name = '"+f_post.cleaned_data['lastname']+"'"
				cursor.execute(query)
				n = cursor.fetchone()[0]
				if n != 0:
					isError_alreay_exist = True
					#keep previously added data in form
					form = f_post
			except User.DoesNotExist:
				pass
			if not isError_alreay_exist:
				#add a user
				u = User.objects.create_user(f_post.cleaned_data['username'], 'lennon@thebeatles.com', f_post.cleaned_data['password'])
				u.first_name = f_post.cleaned_data['firstname']
				u.last_name = f_post.cleaned_data['lastname']
				u.save()
				#add a player
				p = Player()
				p.id = u.id
				p.gameId = game_id
				p.save()
				#add a character sheet
				s = CharacterSheet()
				s.player_id = u.id
				s.body = ""
				s.save()
				return HttpResponseRedirect("/team/playerForMaster/"+str(u.id)+"/")
		else:
			isError = True
			#let previously added data in form
			form = f_post
	pageSelect = rpgEngineHelper.getSelectPageTeam(request.user, game_id, -2)
	stickyBox = rpgEngineHelper.getStickyBox(game_id)
	return render_to_response('rpgEngine/team_add_player.html', {
		'menu':menu,
		'stickyBox':stickyBox,
		'form':form,
		'isError':isError,
		'isError_alreay_exist':isError_alreay_exist,
		'pageSelect':pageSelect,
	}, context_instance=RequestContext(request))



class uploadLibItem(forms.Form):
	uploadLibItemFile = forms.FileField()
	description = forms.CharField(required=False, initial='description...', widget=forms.Textarea(attrs={'class':'library_form_description','onfocus':'description_onfocus(this);','onblur':'description_onblur(this);'}))


def delLibraryItem(request, itemId):
	'''delete from Library the item with id : id'''
	if (rpgEngineHelper.getPlayer(request.user) == None) and (rpgEngineHelper.getMaster(request.user) == None):
		return HttpResponseForbidden()
	userGameId = rpgEngineHelper.getGameId(request.user)
	libItem = LibraryItem.objects.get(id=itemId)
	if not(userGameId == libItem.gameId):
		return HttpResponseForbidden()
	else:
		#remove item from data base and from file system
		try:
			os.remove(settings.MEDIA_ROOT + "games/" + str(libItem.gameId) + "/library/" + libItem.path)
		except:
			pass
		#delete the file ref from DB only if file has been deleted
		if not os.path.exists(settings.MEDIA_ROOT + "games/" + str(libItem.gameId) + "/library/" + libItem.path):
			libItem.delete()
		return HttpResponseRedirect("/library/")


def library(request):
	if (rpgEngineHelper.getPlayer(request.user) == None) and (rpgEngineHelper.getMaster(request.user) == None):
		return HttpResponseForbidden()
	menu = rpgEngineHelper.getMenuList(request.user)
	rpgEngineHelper.updatePresence(request.user)
	form = uploadLibItem(auto_id=True)
	if (request.method == 'POST'):
		f_post = uploadLibItem(request.POST, request.FILES, auto_id=True)
		if f_post.is_valid():
			#a file has been uploaded
			i = LibraryItem()
			gameId = rpgEngineHelper.getGameId(request.user)
			i.gameId = gameId
			i.description = f_post.cleaned_data['description']
			try:
				i.path = rpgEngineHelper.uploadFileToLibrary(gameId, request.FILES['uploadLibItemFile'])
				i.label = i.path
				#save only once file written to disc
				i.save()
			except:
				pass
	#retrieve Library Item list
	libraryItemList = rpgEngineHelper.getLibraryItemList(request.user)
	game_id = rpgEngineHelper.getGameId(request.user)
	stickyBox = rpgEngineHelper.getStickyBox(game_id)
	return render_to_response('rpgEngine/library.html', {
		'menu':menu,
		'stickyBox':stickyBox,
		'form':form,
		'itemList':libraryItemList,
	}, context_instance=RequestContext(request))

class addPlayerForm(forms.Form):
	username = forms.CharField(max_length=30, widget=forms.TextInput(attrs={'class':'add_player_username',}))
	firstname = forms.CharField(label='First name', max_length=30, widget=forms.TextInput(attrs={'class':'add_player_first_name',}))
	lastname = forms.CharField(label='Last name', max_length=30, widget=forms.TextInput(attrs={'class':'add_player_last_name',}))
	password = forms.CharField(widget=forms.TextInput(attrs={'class':'iadd_player_password',}))


class addGameForm(forms.Form):
	username = forms.CharField(max_length=30, widget=forms.TextInput(attrs={'class':'add_game_username',}))
	firstname = forms.CharField(label='First name', max_length=30, widget=forms.TextInput(attrs={'class':'add_game_first_name',}))
	lastname = forms.CharField(label='Last name', max_length=30, widget=forms.TextInput(attrs={'class':'add_game_last_name',}))
	password = forms.CharField(widget=forms.TextInput(attrs={'class':'iadd_player_password',}))
	name = forms.CharField(label='Game Name', max_length=250, widget=forms.TextInput(attrs={'class':'add_game_name','size':'57'}))

def gameList(request):
	if rpgEngineHelper.getAdmin(request.user) == None:
		return HttpResponseForbidden()
	menu = rpgEngineHelper.getMenuList(request.user)
	form = addGameForm(auto_id=True)
	isError = False
	isError_username_alreay_exist = False
	isError_game_name_alreay_exist = False
	if (request.method == 'POST'):
		f_post = addGameForm(request.POST, auto_id=True)
		if f_post.is_valid():
			#a game has been submitted, together with details to create Master account
			#check if username already exist
			try:
				u_tmp = User.objects.get(username__exact=f_post.cleaned_data['username'])
				isError_username_alreay_exist = True
				#let previously added data in form
				form = f_post
			except User.DoesNotExist:
				pass
			if not isError_username_alreay_exist:
				#first check if Game name already exist
				try:
					g = Game.objects.get(name__exact=f_post.cleaned_data['name'])
					isError_game_name_alreay_exist = True
					#let previously added data in form
					form = f_post
				except Game.DoesNotExist:
					pass
				if not isError_game_name_alreay_exist :
					#add a user
					u = User.objects.create_user(f_post.cleaned_data['username'], 'lennon@thebeatles.com', f_post.cleaned_data['password'])
					u.first_name = f_post.cleaned_data['firstname']
					u.last_name = f_post.cleaned_data['lastname']
					u.save()
					#add a Game
					g = Game()
					g.name = f_post.cleaned_data['name']
					g.iscap = 0;
					g.save()
					#load added Game to retrieve id
					g = Game.objects.get(name__exact=f_post.cleaned_data['name'])
					#add a Master
					m = Master()
					m.id = u.id
					m.gameId = g.id
					m.save()
					rpgEngineHelper.createGameStaticFolder(g.id)
		else:
			isError = True
			#let previously added data in form
			form = f_post
	game_list = rpgEngineHelper.getGameList(request.user)
	return render_to_response('rpgEngine/gameList.html', {
		'menu':menu,
		'games':game_list,
		'form':form,
		'isError':isError,
		'isError_username_alreay_exist':isError_username_alreay_exist,
		'isError_game_name_alreay_exist':isError_username_alreay_exist,
	}, context_instance=RequestContext(request))


def index(request):
	'''Display login form or redirect user if logged on already'''
	response = HttpResponse()
	rLogin = login(request,'rpgEngine/login.html','next')
	if request.user.is_authenticated():
		if rpgEngineHelper.getPlayer(request.user) != None:
			return HttpResponseRedirect("/messageBox/")
		if rpgEngineHelper.getMaster(request.user) != None:
			return HttpResponseRedirect("/messageBox/")
		if rpgEngineHelper.getAdmin(request.user) != None:
			return HttpResponseRedirect("/gameList/")
		logout(request)
		return HttpResponseRedirect("/")
	response.write(rLogin.content)
	return response


def suggestAddr(request):
	'''return the list of players and master, except the current player/master, of the current game'''
	if (rpgEngineHelper.getPlayer(request.user) == None) and (rpgEngineHelper.getMaster(request.user) == None):
		return HttpResponseForbidden()
	return HttpResponse(rpgEngineHelper.getAddressSuggestion(request.user))

def notifyReadMsg(request, msgId):
	'''set the message specified by the id as read, for the logged on user'''
	if (rpgEngineHelper.getPlayer(request.user) == None) and (rpgEngineHelper.getMaster(request.user) == None):
		return HttpResponseForbidden()
	rpgEngineHelper.setMsgAsRead(request.user, msgId)
	return  HttpResponse("ok;"+str(msgId))
